package org.aceor.funny.common.http.utils;


import org.aceor.funny.common.http.executor.ResultCallback;

import java.lang.reflect.*;
import java.util.Map;

/**
 * Created by lxue on 15/11/20.
 */
public class TypeUtils {
    public static <T> void singleInterfaceCheck(final Class<T> service){
        if(!service.isInterface()){
            throw new IllegalArgumentException("输入参数必须是接口.");
        }
        if(service.getInterfaces().length > 0 ){
            throw new IllegalArgumentException("输入参数必须是单接口.");
        }
    }

    public static Class<?> getRawType(Type type) {
        if(type instanceof Class) {
            return (Class)type;
        } else if(type instanceof ParameterizedType) {
            ParameterizedType className2 = (ParameterizedType)type;
            Type rawType = className2.getRawType();
            if(!(rawType instanceof Class)) {
                throw new IllegalArgumentException();
            } else {
                return (Class)rawType;
            }
        } else if(type instanceof GenericArrayType) {
            Type className1 = ((GenericArrayType)type).getGenericComponentType();
            return Array.newInstance(getRawType(className1), 0).getClass();
        } else if(type instanceof TypeVariable) {
            return Object.class;
        } else if(type instanceof WildcardType) {
            return getRawType(((WildcardType)type).getUpperBounds()[0]);
        } else {
            String className = type == null?"null":type.getClass().getName();
            throw new IllegalArgumentException("Expected a Class, ParameterizedType, or GenericArrayType, but <" + type + "> is of type " + className);
        }
    }

    /**
     * 不敢说是通用的,故只用于ResultCallback取回泛型参数类型
     * @param callback
     * @return
     */
    public static Type getResultCallbackParameterizedType(ResultCallback callback){
        Type type = callback.getClass().getGenericInterfaces()[0];
        if(type instanceof ParameterizedType){
            ParameterizedType ptype = (ParameterizedType)type;
            //取第一个实际参数,并通过getRawType获取Class.Integer->Integer;List<Integer>->List;EnityType->EntityType;
            return ptype.getActualTypeArguments()[0];
        }
        return null;
    }

    public static String urlCompose(String baseUrl, Map<String, Object> queryMap) {
        StringBuffer url = new StringBuffer(baseUrl);
        boolean hasQues = false;
        if(baseUrl.contains("?")){
            hasQues = true;
        }
        if(queryMap != null && queryMap.size() != 0){
            if(!hasQues){
                url.append('?');
            }else{
                //有问号
                //1. 直接问号结尾 2.a=结尾 3.a=b结尾 4.a(1正常跳过处理;2,3加&;4这种情况异常)
                checkUrlQueryParam(url);
            }
            for(Map.Entry<String, Object> entry:queryMap.entrySet()){
                url.append(entry.getKey())
                        .append("=")
                        .append(entry.getValue())
                        .append('&');
            }
            url.deleteCharAt(url.length()-1);
        }

        return url.toString();
    }

    private static void checkUrlQueryParam(StringBuffer url) {
        //TODO :完善逻辑,这里简化处理
        if(url.indexOf("?") == url.length()){
            //pass
        }else {
            url.append("&");
        }
    }

    public static Type type(final Class raw, final Type... args){
        return new ParameterizedType() {
            public Type[] getActualTypeArguments() {
                return args;
            }

            public Type getOwnerType() {
                return null;
            }

            public Type getRawType() {
                return raw;
            }
        };
    }
}
